🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / app / src / main / java / com / geeksville / mesh / repository / radio / TCPInterface.kt
Displaying Raw • Download
app/src/main/java/com/geeksville/mesh/repository/radio/TCPInterface.kt 78274c792318331b11ab64cd28e58e829875b8c2 (78274c79) Text, 4.87 KB
T8b949e/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787com.geeksville.mesh.repository.radio
Tff7b72import T7ee787com.geeksville.mesh.concurrent.handledLaunch
Tff7b72import T7ee787com.geeksville.mesh.repository.network.NetworkRepository
Tff7b72import T7ee787com.geeksville.mesh.util.Exceptions
Tff7b72import T7ee787dagger.assisted.Assisted
Tff7b72import T7ee787dagger.assisted.AssistedInject
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787kotlinx.coroutines.delay
Tff7b72import T7ee787kotlinx.coroutines.withContext
Tff7b72import T7ee787timber.log.Timber
Tff7b72import T7ee787java.io.BufferedInputStream
Tff7b72import T7ee787java.io.BufferedOutputStream
Tff7b72import T7ee787java.io.IOException
Tff7b72import T7ee787java.io.OutputStream
Tff7b72import T7ee787java.net.InetAddress
Tff7b72import T7ee787java.net.Socket
Tff7b72import T7ee787java.net.SocketTimeoutException
Tff7b72class T56d364TCPInterface Tf0883e@AssistedInject Tff7b72constructorTb4b4b4(Te6edf3serviceTb4b4b4: Te6edf3RadioInterfaceServiceTb4b4b4, Tf0883e@Assisted Tff7b72private Tff7b72val Te6edf3addressTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4:
Te6edf3StreamInterfaceTb4b4b4(Te6edf3serviceTb4b4b4) Tb4b4b4{
Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72const Tff7b72val Te6edf3MAX_RETRIES_ALLOWED Tff7b72= Tffa657IntTb4b4b4.Te6edf3MAX_VALUE
Tff7b72const Tff7b72val Te6edf3MIN_BACKOFF_MILLIS Tff7b72= T79c0ff1 Tff7b72* T79c0ff1T79c0ff0T79c0ff0T79c0ff0L T8b949e// 1 second
Tff7b72const Tff7b72val Te6edf3MAX_BACKOFF_MILLIS Tff7b72= T79c0ff5 Tff7b72* T79c0ff6T79c0ff0 Tff7b72* T79c0ff1T79c0ff0T79c0ff0T79c0ff0L T8b949e// 5 minutes
Tff7b72const Tff7b72val Te6edf3SERVICE_PORT Tff7b72= Te6edf3NetworkRepositoryTb4b4b4.Te6edf3SERVICE_PORT
Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3retryCount Tff7b72= T79c0ff1
Tff7b72private Tff7b72var Te6edf3backoffDelay Tff7b72= Te6edf3MIN_BACKOFF_MILLIS
Tff7b72private Tff7b72var Te6edf3socketTb4b4b4: Te6edf3Socket? Tff7b72= Tff7b72null
Tff7b72private Tff7b72lateinit Tff7b72var Te6edf3outStreamTb4b4b4: Te6edf3OutputStream
Tff7b72init Tb4b4b4{
Te6edf3connectTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsendBytesTb4b4b4(Te6edf3pTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tb4b4b4{
Te6edf3outStreamTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffflushBytesTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3outStreamTb4b4b4.Te6edf3flushTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffonDeviceDisconnectTb4b4b4(Te6edf3waitForStoppedTb4b4b4: Tffa657BooleanTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3s Tff7b72= Te6edf3socket
Tff7b72if Tb4b4b4(Te6edf3s Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffClosing TCP socketTa5d6ff"Tb4b4b4)
Te6edf3sTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Te6edf3socket Tff7b72= Tff7b72null
Tb4b4b4}
Tff7b72superTb4b4b4.Te6edf3onDeviceDisconnectTb4b4b4(Te6edf3waitForStoppedTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffconnectTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3serviceTb4b4b4.Te6edf3serviceScopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{
Tff7b72while Tb4b4b4(Tff7b72trueTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3startConnectTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3IOExceptionTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Ta5d6ff"Ta5d6ffIOException in TCP reader: Tffd700$Te6edf3exTa5d6ff"Tb4b4b4)
Te6edf3onDeviceDisconnectTb4b4b4(Tff7b72falseTb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3ThrowableTb4b4b4) Tb4b4b4{
Te6edf3ExceptionsTb4b4b4.Te6edf3reportTb4b4b4(Te6edf3exTb4b4b4, Ta5d6ff"Ta5d6ffException in TCP readerTa5d6ff"Tb4b4b4)
Te6edf3onDeviceDisconnectTb4b4b4(Tff7b72falseTb4b4b4)
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3retryCount Tff7b72> Te6edf3MAX_RETRIES_ALLOWEDTb4b4b4) Tff7b72break
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffReconnect attempt Tffd700$Te6edf3retryCountTa5d6ff in Tffd700${Te6edf3backoffDelay Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0Tffd700}Ta5d6ffsTa5d6ff"Tb4b4b4)
Te6edf3delayTb4b4b4(Te6edf3backoffDelayTb4b4b4)
Te6edf3retryCountTff7b72+Tff7b72+
Te6edf3backoffDelay Tff7b72= Te6edf3minOfTb4b4b4(Te6edf3backoffDelay Tff7b72* T79c0ff2Tb4b4b4, Te6edf3MAX_BACKOFF_MILLISTb4b4b4)
Tb4b4b4}
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffExiting TCP readerTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e// Create a socket to make the connection with the server
Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffstartConnectTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3IOTb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffTCP connecting to Tffd700$Te6edf3addressTa5d6ff"Tb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3hostTb4b4b4, Te6edf3portTb4b4b4) Tff7b72=
Te6edf3addressTb4b4b4.Te6edf3splitTb4b4b4(Ta5d6ff"Ta5d6ff:Ta5d6ff"Tb4b4b4, Te6edf3limit Tff7b72= T79c0ff2Tb4b4b4)Tb4b4b4.Te6edf3let Tb4b4b4{ Tffa657itTff7b72[T79c0ff0Tff7b72] Te6edf3to Tb4b4b4(Tffa657itTb4b4b4.Te6edf3getOrNullTb4b4b4(T79c0ff1Tb4b4b4)Tff7b72?.Te6edf3toIntOrNullTb4b4b4(Tb4b4b4) Tff7b72?: Te6edf3SERVICE_PORTTb4b4b4) Tb4b4b4}
Te6edf3SocketTb4b4b4(Te6edf3InetAddressTb4b4b4.Te6edf3getByNameTb4b4b4(Te6edf3hostTb4b4b4)Tb4b4b4, Te6edf3portTb4b4b4)Tb4b4b4.Te6edf3use Tb4b4b4{ Te6edf3socket Tff7b72-Tff7b72>
Te6edf3socketTb4b4b4.Te6edf3tcpNoDelay Tff7b72= Tff7b72true
Te6edf3socketTb4b4b4.Te6edf3soTimeout Tff7b72= T79c0ff5T79c0ff0T79c0ff0
Tff7b72thisTf0883e@TCPInterface.socket Tff7b72= Te6edf3socket
Te6edf3BufferedOutputStreamTb4b4b4(Te6edf3socketTb4b4b4.Te6edf3getOutputStreamTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3use Tb4b4b4{ Te6edf3outputStream Tff7b72-Tff7b72>
Te6edf3outStream Tff7b72= Te6edf3outputStream
Te6edf3BufferedInputStreamTb4b4b4(Te6edf3socketTb4b4b4.Te6edf3getInputStreamTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3use Tb4b4b4{ Te6edf3inputStream Tff7b72-Tff7b72>
Tff7b72superTb4b4b4.Te6edf3connectTb4b4b4(Tb4b4b4)
Te6edf3retryCount Tff7b72= T79c0ff1
Te6edf3backoffDelay Tff7b72= Te6edf3MIN_BACKOFF_MILLIS
Tff7b72var Te6edf3timeoutCount Tff7b72= T79c0ff0
Tff7b72while Tb4b4b4(Te6edf3timeoutCount Tff7b72< T79c0ff1T79c0ff8T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{ T8b949e// close after 90s of inactivity
Tff7b72val Te6edf3c Tff7b72= Te6edf3inputStreamTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3c Tff7b72=Tff7b72= Tff7b72-T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3wTb4b4b4(Ta5d6ff"Ta5d6ffGot EOF on TCP streamTa5d6ff"Tb4b4b4)
Tff7b72break
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3timeoutCount Tff7b72= T79c0ff0
Te6edf3readCharTb4b4b4(Te6edf3cTb4b4b4.Te6edf3toByteTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3exTb4b4b4: Te6edf3SocketTimeoutExceptionTb4b4b4) Tb4b4b4{
Te6edf3timeoutCountTff7b72+Tff7b72+
T8b949e// Ignore and start another read
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3onDeviceDisconnectTb4b4b4(Tff7b72falseTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.06s